<?php  namespace App\Models;

use App\Utils\CommonUtils;
use App\Models\VerifyCode;
use App\Models\VerifyCodeLog;
use App\Models\User;
use App\Models\Attention;
use App\Models\Topic;
use App\Models\Program;
use App\Cache\MRedis;
use Log;
class User extends BaseModel{
    
	//表明
	protected $table = 'user';
	//主键
	protected $primaryKey = 'id';
	
    //获取用户信息
    public function getUserObject($Obj=null){
        $object = array();
        $id;
        if($Obj){
            $id = $Obj['id'];
            $object['userId'] = $Obj['id'];
            $object['nickname'] = $Obj['name'];
            $object['userType'] = $Obj['type'];
            $object['userIcon'] = $Obj['img']?$Obj['img']:'978a07f6d14d514791d747cdddf58951';
            $object['slogan'] = $Obj['slogan'];
            $object['birthday'] = $Obj['birthday'];
            $object['gender'] = $Obj['gender'];
        }else{
            $id = $this->id;
            $object['userId'] = $this->id;
            $object['nickname'] = $this->name;
            $object['userType'] = $this->type;
            $object['userIcon'] = $this->img?$this->img:'978a07f6d14d514791d747cdddf58951';
            $object['slogan'] = $this->slogan;
            $object['birthday'] = $this->birthday;
            $object['gender'] = $this->gender;
            
        }
        $object['isFollow'] = 0; //是否关注 0 未关注 1 关注
        $object['fansTotal'] = 0;
        $object['followTotal'] = 0;
        //实时查询状态
        $userId = $this->request->input('userId');
        if(env('OPENCACHE', '0')){
            $mRedis = new MRedis();
            if($userId){
                $ret = $mRedis->IsFollowUser($userId, $id);
                if($ret){
                    $object['isFollow'] = 1;
                }
            }
            $sum = $mRedis->getFansTotal($id);
            if($sum){
                $object['fansTotal'] = $sum;
            }
            $sum1 = $mRedis->getFollowerTotal($id);
            if($sum1){
                $object['followTotal'] = $sum1;
            }
        }else{
            if($userId && $userId != $id){
                $follower = Followers::select('id')
                        ->where('user_id','=',$userId)
                        ->where('follow_id','=',$id)
                        ->where('is_delete','=',0)
                        ->first();
                if($follower) {
                    $object['isFollow'] = 1;
                }
            }
        }
        return $object;
    }
    
     public function getUserById($userId){
        $user = User::select('id','token','phone','status','is_delete')
                ->where('status','=',1)
                ->where('is_delete','=',0)
                ->where('id','=',$userId)
                ->first();
        return $user;
    }
    
    //获取自己用户信息
    public function getMyUserObject($dk=null){
        $object = array();
        $object['userId'] = $this->id;
        $object['nickname'] = $this->name;
        $object['userType'] = $this->type;
        $object['userIcon'] = $this->img;
        $object['slogan'] = $this->slogan;
        $object['birthday'] = $this->birthday;
        $object['gender'] = $this->gender;
        $object['isFollow'] = 1; //是否关注 0 未关注 1 关注
        $object['fansTotal'] = 0;
        $object['followTotal'] = 0;
        if(env('OPENCACHE', '0')){
            $mRedis = new MRedis();
            $ret = $mRedis->IsFollowUser($this->id, $this->id);
            if($ret){
                $object['isFollow'] = 1;
            }
            $sum = $mRedis->getFansTotal($this->id);
            if($sum){
                $object['fansTotal'] = $sum;
            }
            $sum1 = $mRedis->getFollowerTotal($this->id);
            if($sum1){
                $object['followTotal'] = $sum1;
            }
        }
        if($this->token){
            $jsonObj = json_decode($this->token);
            foreach ($jsonObj as $key=>$val){
                if($dk == $key){
                    if(!$val->tn){
                        return 1;//未登录
                    }
                    if(time() - $val->time > 30*24*60*60){
                        return 2;//过期
                    }
                    $object['tn'] = $val->tn; 
                    break;
                }
            }
        }
        return $object;
    }
    
    //同步用户信息
    public function syncUser(){
        $uuid = $this->request->input('uuid');
        $phone = $this->request->input('phone');
        $user = $this->select('id','uid','img','name','phone','slogan','birthday','gender','type','status','is_delete')
                ->where('phone','=',$phone)
                ->first();
        if($user){
            if($user->is_delete == 1 || $user->status != 1){ // 用户被删除或被禁用
                return ;
            }
            $user->request = $this->request;
            return $user->getUserObject();
        }
        $img = with(new CommonUtils())->getRandImg();
        $user = new User();
        $user->img = $img;
        $user->uid = $uuid;
        $user->phone = $phone;
        $user->name = '小'. with(new CommonUtils($this->request))->getRandChar(1);
        $user->type = 1;
        $user->save();
        return $user->getMyUserObject();
        
    }
    
    //关注话题和电影
    public function attention(){
        $userId = $this->request->input('userId');
        $type = $this->request->input('type');
        $id = $this->request->input('id');
        if(env('OPENCACHE', '0')){
            $mRedis = new MRedis();
            $ret = FALSE;
            if($type == 1){//话题
                $ret = $mRedis->userAttentionTopic('add',$userId, $id);
            }elseif($type == 2){//视频
                $ret = $mRedis->userAttentionProgram('add',$userId, $id);
            }
            return $ret;
        }else{
            $attention = new Attention();
            $attention->user_id = $userId;
            $attention->item_id = $id;
            $attention->type = $type;
            if($type == 1){//话题
                $attention->type = 1;
            }elseif($type == 2){//视频
                $attention->type = 2;
            }
            $ret = $attention->save();
            return $ret;
        }
    }
    //取消关注
    public function deleteAttention(){
        $userId = $this->request->input('userId');
        $type = $this->request->input('type');
        $id = $this->request->input('id');
        if(env('OPENCACHE', '0')){
            $mRedis = new MRedis();
            if($type == 1){//话题
                $ret = $mRedis->userAttentionTopic('delete',$userId, $id);
                return $ret;
            }elseif($type == 2){//视频
                $ret = $mRedis->userAttentionProgram('delete',$userId, $id);
                return $ret;
            }else{
                return FALSE;
            }
        }else{
            $attention = Attention::select('id','user_id','type','item_id','is_delete')
                    ->where('user_id', '=', $userId)
                    ->where('type', '=', $type)
                    ->where('item_id', '=', $id)
                    ->first();
            $ret = FALSE;
            if($attention){
                if($attention->is_delete == 0){
                    $attention->is_delete = 1;
                    $ret = $attention->save();
                }
            }
            return $ret;
        }
    }
    
    //取消所有关注
    public function deleteAllAttention(){
        $userId = $this->request->input('userId');
        $type = $this->request->input('type');
        if(env('OPENCACHE', '0')){
            $mRedis = new MRedis();
            if($type == 1){//话题
                $ret = $mRedis->userAttentionTopic('deleteAll',$userId, 0);
                return $ret;
            }elseif($type == 2){//视频
                $ret = $mRedis->userAttentionProgram('deleteAll',$userId, 0);
                return $ret;
            }else{
                return FALSE;
            }
        }else{
            $attentions = Attention::select('id','user_id','type','item_id','is_delete')
                    ->where('user_id', '=', $userId)
                    ->where('type', '=', $type)
                    ->update(['is_delete'=>1]);
            if($attentions){
                return TRUE;
            }else{
                return FALSE;
            }
        }
    }
    //获取用户关注的列表
    public function getAttentionList() {
        $userId = $this->request->input('userId');
        $uId = $this->request->input('uId');
        $page = $this->request->input('page');
        $type = $this->request->input('type');
        $size = $this->request->input('size');
        if(env('OPENCACHE', '0')){
            $mRedis = new MRedis();
            if($type == 1){//话题
                $ids = $mRedis->getAttentionTopicIdsByUserId($uId, $page, $size);
                $size = count($ids);
                $data = [];
                $data['data'] = [];
                $data['paging']['size'] = 0;
                if($size > 0){
                    foreach ($ids as $key => $val){
                        $temp = with(new Topic($this->request))->getRedisTopicObject($key);
                        if($temp){
                            $data['data'][] = $temp;
                        }
                    }
                    if(is_array($data['data'])){
                        $data['paging']['size'] = $size;
                    }
                }
                return $data;
            }else if($type == 2){
                $ids = $mRedis->getAttentionProgramIdsByUserId($uId, $page, $size);
                $size = count($ids);
                $data = [];
                $data['data'] = [];
                $data['paging']['size'] = 0;
                if($size > 0){
                    foreach ($ids as $key => $val){
                        $temp = with(new Program($this->request))->getRedisProgramObject($key);
                        if($temp){
                            $data['data'][] = $temp;
                        }
                    }
                    if(is_array($data['data'])){
                        $data['paging']['size'] = $size;
                    }
                }
                return $data;
            }
        }else{
            if($type == 1){//话题
                $dataList = Topic::select('topic.id','topic.title','topic.img','topic.introduction','topic.keywords','topic.created_by','topic.sort')
                    ->where('topic.is_delete','=',0)
                    ->where('topic.status','=',1)
                    ->join('attention','attention.item_id','=','topic.id')
//                    ->join('user','user.id','=','attention.user_id')
//                    ->where('user.id','=',$uId)
//                    ->where('user.is_delete','=',0)
                    ->where('attention.type','=',1)//话题
                    ->where('attention.is_delete','=',0)
                    ->orderBy('attention.updated_at','desc')
                    ->skip($page*$size)
                    ->take($size)
                    ->get();
                    $data = array();
                    $data['data'] = array();
                    $data['paging']['size'] = 0;
                    foreach ($dataList as $key => $val) {
                        $val->request = $this->request;
                        $data['data'][] = $val->getTopicObject();
                    }
                    if(isset($data['data'])){
                        $data['paging']['size'] = count($data['data']);
                    }
                    return $data;
            }else{//电影
                $dataList = Program::select('program.id','program.name','program.keywords','program.video_url','program.img_broad','program.img_tall','program.directors','program.scriptwriter','program.actors','program.area','program.publish_time','program.type','program.introduction','program.publish_time')
                    ->where('program.is_delete','=',0)
    //                ->where('program.status','=',1)
                    ->join('attention','attention.item_id','=','program.id')
                    ->where('attention.type','=',2)//电影
                    ->where('attention.is_delete','=',0)
                    ->orderBy('attention.updated_at','desc')
                    ->skip($page*$size)
                    ->take($size)
                    ->get();
                    $data = array();
                    $data['data'] = array();
                    $data['paging']['size'] = 0;
                    foreach ($dataList as $key => $val) {
                        $val->request = $this->request;
                        $data['data'][] = $val->getProgramObject();
                    }
                    if(isset($data['data'])){
                        $data['paging']['size'] = count($data['data']);
                    }
                    return $data;
            }
        }
    }
    
    public function verifyCode() {
        $phone = $this->request->input('phone');
        $type = $this->request->input('type');
        $deviceId = $this->request->input('dk');
        if(!preg_match("/^1[3456789]{1}\d{9}$/",$phone)){  
            return 1;//手机格式错误
        }
        $limit = $this->isCodeLimit();
        if($limit){
            return 2;//超过每日次数
        }
        $msg['phone'] = $phone;
        $msg['code'] = rand(100000,999999);
//        $msg['code'] = 620933;
        $ret = with(new CommonUtils())->sendShortMessage($msg);
//        $ret = TRUE;
        if($ret){
            //成功
            $vcode = VerifyCode::select('id',"phone","src_code",'sum',"updated_at")
                ->where('phone', '=', $phone)
                ->first();
            if($vcode){
                $sum = (int)$vcode->sum + 1;
                $vcode->src_code = $msg['code'];
                $vcode->sum = $sum;
                $vcode->is_delete = 0;
                $vcode->save();
            }else{
                $vcode = new VerifyCode();
                $vcode->src_code = $msg['code'];
                $vcode->phone = $phone;
                $vcode->sum = 1;
                $vcode->is_delete = 0;
                $vcode->save();
            }
            $vLogcode = new VerifyCodeLog();
            $vLogcode->phone = $phone;
            $vLogcode->device_id = $deviceId;
            $vLogcode->ip = $this->getRealIp();
            $vLogcode->code = $msg['code'];
            $vLogcode->save();
            return 0;//成功
        }else{
            return 3;//获取失败
        }
        
    }
    public function login() {
        $phone = $this->request->input('phone');
        $code = $this->request->input('code');
        $vcode = VerifyCode::select('id',"phone","src_code","updated_at")
                ->where('phone', '=', $phone)
                ->where('is_delete', '=', 0)
                ->first();
        if(!$vcode){
            return 1;//验证码有误
        }
        if($vcode->src_code == $code){
            $ret = $this->register();
            return $ret;
        }else{
            return 1;//验证码有误
        }
    }
    //登出
    public function logout() {
        $userId = $this->request->input('userId');
        $deviceId = $this->request->input('dk');
        //登出
        $user = User::select('id','uid','token','img','name','phone','slogan','birthday','gender','type','status','is_delete')
                ->where('id', '=', $userId)
                ->first();
        if($user){
            if($user->token){
                $jsont = json_decode($user->token);
                foreach ($jsont as $key=>$val){
                    if($key == $deviceId){
                        $jsont->$key->tn = '';//置空
                        $jsont->$key->time = time();
                    }
                }
                $user->token = json_encode($jsont);
                $user->save();
                return ['status'=>0,'msg'=>'退出成功'];
            }else{
                
            }
        }
        return ['status'=>0,'msg'=>'退出成功'];
    }
    //是否是注册用户,不是就注册
    public function register(){
        $phone = $this->request->input('phone');
        $deviceId = $this->request->input('dk');
        $token;
//        $deviceId = '087654321';
        $user = User::select('id','uid','token','img','name','phone','slogan','birthday','gender','type','status','is_delete')
                ->where('phone', '=', $phone)
                ->first();
        if($user){//已注册手机号
            $token = md5(uniqid(time()));
            if($user->token){//有数据
//                $ret = $this->isLoginLimit($user->token);//是否登录设备超过限制
                $ret = FALSE;
                if($ret){
                    return 2;//超过设备数量限制
                }
                $obj = json_decode($user->token);
                if(isset($obj->$deviceId)){
                    $obj->$deviceId->tn = $token;
                    $obj->$deviceId->time = time();
                }else{
                    $obj->$deviceId = array(
                        "tn"=>$token,   //32位串
                        "time"=>time(),
                    );
                }
                $user->token = json_encode($obj);
                $ret = $user->save();
                if($ret && env('OPENCACHE', '0')){
                    $mRedis = new MRedis();
                    $ret = $mRedis->handleEntity('add', 'user', $user->id);
                }
            }else{
                $data[$deviceId] = array(
                    "tn"=>$token,   //32位串
                    "time"=>time(),
                );
                $user->token = json_encode($data);
                $ret = $user->save();
                if($ret && env('OPENCACHE', '0')){
                    $mRedis = new MRedis();
                    $ret = $mRedis->handleEntity('add', 'user', $user->id);
                }
            }
            return $user->getMyUserObject($deviceId);
        }else{//未注册
            $newUser  = new User();
            $t = md5(uniqid(time()));
            $data = array();
            $data[$deviceId] = array(
                "tn"=>$t,   //32位串
                "time"=>time(),
            );
            $jsondata = json_encode($data);
            $newUser->phone = $phone;
            $newUser->token = $jsondata;
            $newUser->img = $img = with(new CommonUtils())->getRandImg();//随机头像
            $newUser->name = "小".with(new CommonUtils())->getRandChar(1);//随机生成name
            $newUser->type = 1;
            $r = $newUser->save();
            //登录返回数据
            if($r){
                if(env('OPENCACHE', '0')){
                    $mRedis = new MRedis();
                    $ret = $mRedis->handleEntity('add', 'user', $newUser->id);
                }
                return $newUser->getMyUserObject($deviceId);
            }
        }
    }
    //是否登录设备超过限制
    protected function isLoginLimit($jsonstr) {
        $obj = json_decode($jsonstr);
        $t = array();
        if($obj){
            $t = time() - 30*24*60*60;//一个月
            $n = 0;
            foreach ($obj as $key=>$val){
                if($val->time > $t && $val->tn){
                    $n++;
                }
            }
            if($n > 5){
                return 1;//超过登录设备数
            }
            return 0;
        }
        return 0;
    }
    //判断获取验证码次数是否超过限制
    protected function isCodeLimit() {
        $phone = $this->request->input('phone');
        $deviceId = $this->request->input('dk');
        $IP = $this->getRealIp();
        $todaytime=strtotime("today");
        $vphone = VerifyCodeLog::select('id',"phone","code","updated_at")
                ->where('phone', '=', $phone)
                ->where('is_delete', '=', 0)
                ->where('updated_at', '>', $todaytime)
                ->where('updated_at', '<', $todaytime + 24*60*60)
                ->get();
        if($vphone && count($vphone) > 10){//每个手机号每天10条
            return 1;
        }
        $vdevice = VerifyCodeLog::select('id',"phone","code","updated_at")
                ->where('device_id', '=', $deviceId)
                ->where('is_delete', '=', 0)
                ->where('updated_at', '>', $todaytime)
                ->where('updated_at', '<', $todaytime + 24*60*60)
                ->get();
        if($vdevice && count($vdevice) > 10){//每个设备id每天10条
            return 2;
        }
        $vip = VerifyCodeLog::select('id',"phone","code","updated_at")
                ->where('ip', '=', $IP)
                ->where('is_delete', '=', 0)
                ->where('updated_at', '>', $todaytime)
                ->where('updated_at', '<', $todaytime + 24*60*60)
                ->get();
        if($vip && count($vip) > 50){//每个IP每天50条
            return 3;
        }
        return 0;
    }
    public function getRealIp()
    {
        $ip=false;
        if(!empty($_SERVER["HTTP_CLIENT_IP"])){
          $ip = $_SERVER["HTTP_CLIENT_IP"];
        }
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
          $ips = explode (", ", $_SERVER['HTTP_X_FORWARDED_FOR']);
          if ($ip) { array_unshift($ips, $ip); $ip = FALSE; }
          for ($i = 0; $i < count($ips); $i++) {
            if (!eregi ("^(10│172.16│192.168).", $ips[$i])) {
              $ip = $ips[$i];
              break;
            }
          }
        }
        return ($ip ? $ip : $_SERVER['REMOTE_ADDR']);
    }
    //
    public function updateUserInfo(){
        $userId = $this->request->input('userId');
        $userIcon = $this->request->input('userIcon');
        $nickname = $this->request->input('nickname');
        $birthday = $this->request->input('birthday');
        $slogan = $this->request->input('slogan');
        $gender = $this->request->input('gender');
        $deviceId = $this->request->input('dk');
        $user = User::select('id','uid','token','img','name','phone','slogan','birthday','gender','type','status','is_delete')
                ->where('id', '=', $userId)
                ->where('is_delete', '=', 0)
                ->where('status', '=', 1)
                ->first();
        if($user){
            if($userIcon){
                $user->img = $userIcon;
            }
            if($nickname){
                $user->name = $nickname;
            }
            if($birthday){
                $user->birthday = $birthday;
            }
            if($slogan){
                $user->slogan = $slogan;
            }
            if($gender){
                $user->gender = $gender;
            }
            $ret = $user->save();
            if($ret && env('OPENCACHE', '0')){
                $mRedis = new MRedis();
                $ret = $mRedis->handleEntity('add', 'user', $user->id);
            }
            return $user->getMyUserObject($deviceId);
        }
        return FALSE;
    }
    //获取用户信息
    public function getUserInfo(){
        $userId = $this->request->input('userId');
        $uId = $this->request->input('uId');
        if(env('OPENCACHE', '0')){
            return $this->getRedisUserObject($uId);
        }
        $user = $this->select('id','uid','img','name','phone','slogan','birthday','gender','type','status','is_delete')
                ->where('id','=',$uId)
                ->where('is_delete', '=', 0)
                ->where('status', '=', 1)
                ->first();
        if($user){
            $user->request = $this->request;
            return $user->getUserObject();
        }
        return ['status'=> 1,'msg'=>"获取失败"];
    }
    //获取检索用户结果
    public function getSearchUser(){
        $keywords = $this->request->input('keywords');
        $page = $this->request->input('page');
        $size = $this->request->input('size');
        $dataList = $this->select('id','uid','img','name','phone','slogan','birthday','gender','type','status','is_delete')
                ->where( function($query) use($keywords){
                    $keywords_arr = explode(',', $keywords);
                    foreach ($keywords_arr as $key => $value) {
                        $value = trim($value);
                        if($key === 0){
                            $query->where('name','like','%'.$value.'%');
                        }else{
                            $query->orWhere('name','like','%'.$value.'%');
                        }
                    }
                })
                ->where('status','=',1)
                ->orderBy('created_at','desc')
                ->skip($page*$size)
                ->take($size)
                ->get();
        $data = [];
        $data['data'] = [];
        $data['paging']['size'] = 0;
        if($dataList){
            foreach ($dataList as $val) {
                $val->request = $this->request;
                $data['data'][] = $val->getUserObject();
            }
            if(is_array($data['data'])){
                $data['paging']['size'] = count($data['data']);
            }
        }
        return $data;
    }
    
    //获取redis的实体数据
    public function getRedisUserObject($Id){
        $mRedis = new MRedis();
        $Obj = $mRedis->getEntity('user', $Id);//获取实体
        if(!$Obj && $Id){
            Log::info("getRedisUserObject:取数据库,id=".$Id);
            $ObjData = $this->select('user.id','user.name','user.type','user.img','user.phone')
                    ->where('user.is_delete','=',0)
                    ->where('user.status','=',1)
                    ->where('user.id','=',$Id)
                    ->first();
            if($ObjData){
                $ObjData->request = $this->request;
                return $ObjData->getUserObject();
            }else{
                return FALSE;
            }
        }else{
//            $c = new User($this->request);
            return $this->getUserObject($Obj);
        }
    }
}